
/**
 * imagecache.cpp
 * 
 * ImageCache is the cache of profile image
 * 
 * Copyright (c) 2008 Harunobu Oyama <nobukichi at gmail.com>
 * Licensed under GNU GPL version 3
 *
 */

#include <QCoreApplication>
#include <QUrl>
#include "imagecache.h"

ImageCache* ImageCache::theInstance = 0;

ImageCache* ImageCache::getInstance()
{
	if (theInstance == 0) {
		theInstance = new ImageCache(QCoreApplication::instance());
	}

	return theInstance;
}
	
QIcon ImageCache::icon(const QString& user, const QString& url)
{
	QString imageUrl = (url.isEmpty() ? userToUrl[user] : url);

	if (imageUrl.isEmpty()) {
		return defaultIcon;
	}

	userToUrl[user] = imageUrl;

	MapUrlToIcon::iterator i = urlToIcon.find(imageUrl);
	if (i != urlToIcon.end()) {
		//! requested icon is already in cache
		return i->second;
	}

	//! check if the icon is being downloaded or not
	bool beingDownloaded = false;
	RequestMap::iterator j = activeRequests.begin();
	for (; j != activeRequests.end(); ++j) {
		if (j->second.url() == imageUrl) {
			beingDownloaded = true;
			break;
		}
	}

	//! if not, start downloading it
	if (!beingDownloaded) {
		sendGetIconRequest(imageUrl);
	}

	return defaultIcon;
}
	
ImageCache::ImageCache(QObject* parent)
  : QObject(parent), defaultIcon(":/images/nobita.png")
{
	connect( &http, SIGNAL(requestFinished(int, bool)), 
	         this, SLOT(slotRequestFinished(int, bool)) );
}

ImageCache::~ImageCache()
{
	reset();
}

void ImageCache::reset()
{
	http.abort();
}

void ImageCache::sendGetIconRequest(const QString& iconUrl)
{
	QUrl url(iconUrl);
	http.setHost(url.host());
	
	Request request(iconUrl);
	int requestId = http.get(iconUrl, request.responseBuffer());
	activeRequests[requestId] = request;
}
	
void ImageCache::slotRequestFinished(int id, bool error)
{
	if (!error) {
		RequestMap::iterator it = activeRequests.find(id);
		if (it != activeRequests.end()) {
			if (http.lastResponse().statusCode() == 200) {
				QString url = it->second.url();
				QByteArray body = it->second.responseBuffer()->data();
				QPixmap pixmap;
				pixmap.loadFromData(body);
				urlToIcon[url] = QIcon(pixmap);
				emit signalImageDownloaded();
			}
		}
	}
	
	activeRequests.erase(id);
}

ImageCache::Request::Request(const QString& url)
  : imageUrl(url), ptrResponseBuffer(new QBuffer())
{
}

QBuffer* ImageCache::Request::responseBuffer()
{
	return ptrResponseBuffer.get();
}

QString ImageCache::Request::url() const
{
	return imageUrl;
}

